home *** CD-ROM | disk | FTP | other *** search
/ APDL Other Worlds / APDL Other Worlds Collection.iso / SF3000 / Extras / !FednetCmp / c / SaveFile < prev    next >
Encoding:
Text File  |  2003-10-16  |  11.5 KB  |  344 lines

  1. /*
  2.  *  FednetCmp - Fednet file compression/decompression
  3.  *  Single file savebox
  4.  *  Copyright (C) 2001  Chris Bazley
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public Licence as published by
  8.  *  the Free Software Foundation; either version 2 of the Licence, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public Licence for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public Licence
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /* ANSI library files */
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdbool.h>
  26.  
  27. /* RISC OS library files */
  28. #include "toolbox.h"
  29. #include "saveas.h"
  30. #include "window.h"
  31. #include "gadgets.h"
  32. #include "event.h"
  33. #include "flex.h"
  34.  
  35. /* My library files */
  36. #include "err.h"
  37. #include "msgtrans.h"
  38. #include "Macros.h"
  39. #include "ViewsMenu.h"
  40. #include "SFformats.h"
  41. #include "NoBudge.h"
  42. #include "timer.h"
  43. #include "hourglass.h"
  44. #include "TboxBugs.h"
  45. #include "FilePerc.h"
  46.  
  47. /* Local headers */
  48. #include "Utils.h"
  49. #include "Main.h"
  50. #include "SaveFile.h"
  51.  
  52. /* gadget IDs */
  53. #define SAVEFILE_SSFILETYPE     0x01
  54.  
  55. typedef struct _SaveFileBlk
  56. {
  57.   ObjectId  saveas_id;
  58.   ObjectId  window_id;
  59.   char     *reset_file_name;
  60.   void     *buffer;
  61.   bool      no_budge;
  62.   bool      compress;
  63.   char      reset_filetype[32];
  64. } SaveFileBlk;
  65.  
  66. /* ----------------------------------------------------------------------- */
  67. /*                       Function prototypes                               */
  68.  
  69. static ToolboxEventHandler _SaveFile_savehandler, _SaveFile_ramhandler, _SaveFile_typehandler, _SaveFile_savecompleted, _SaveFile_deletedhandler, _SaveFile_buttonshandler;
  70.  
  71. /* ----------------------------------------------------------------------- */
  72. /*                         Public functions                                */
  73.  
  74. ObjectId SaveFile_create(char *savepath, bool data_saved, flex_ptr buffer, bool compress)
  75. {
  76.   /* Open savebox for data - if success, reanchors flex block. */
  77.   SaveFileBlk *newblk;
  78.   char *views_path, *list_tok, *obj_templ;
  79.   int output_type;
  80.  
  81.   /* Grab memory */
  82.   newblk = malloc(sizeof(SaveFileBlk));
  83.   if(newblk == NULL)
  84.     MG_RETV("NoMem", NULL_ObjectId) /* failure */
  85.   newblk->reset_file_name = NULL;
  86.   newblk->compress = compress;
  87.   newblk->no_budge = false; /* we aren't preventing flex budging */
  88.  
  89.   if(compress) {
  90.     /* Save data uncompressed */
  91.     list_tok = "CompDialogueList";
  92.     obj_templ = "SaveFednet";
  93.     output_type = FILETYPE_FEDNET;
  94.   }
  95.   else {
  96.     /* Save data compressed */
  97.     list_tok = "DeCompDialogueList";
  98.     obj_templ = "SaveFile";
  99.     output_type = FILETYPE_DATA;
  100.   }
  101.  
  102.   /* Create object */
  103.   if(E(toolbox_create_object(0, obj_templ, &newblk->saveas_id)))
  104.     goto errexit_free;
  105.   if(compress) {
  106.     /* Get ObjectId of custom compression savebox with filetype selection */
  107.     if(E(saveas_get_window_id(0, newblk->saveas_id, &newblk->window_id)))
  108.       goto errexit_delete;
  109.   } else
  110.     newblk->window_id = newblk->saveas_id;
  111.  
  112.   /* Store default settings */
  113.   if((newblk->reset_file_name = copystring(savepath)) == NULL)
  114.     goto errexit_delete;
  115.   if(compress) {
  116.     if(E(stringset_get_selected(0, newblk->window_id, SAVEFILE_SSFILETYPE, &newblk->reset_filetype, sizeof(newblk->reset_filetype), NULL)))
  117.       goto errexit_delete;
  118.   }
  119.  
  120.   /* Add entry to iconbar menu */
  121.   if(data_saved)
  122.     views_path = savepath; /* we have real filepath */
  123.   else
  124.     views_path = ""; /* dummy filepath */
  125.   if(E(ViewsMenu_add(newblk->saveas_id, msgs_lookup_sub1(list_tok, tail(savepath, 3)), views_path)))
  126.     goto errexit_delete;
  127.  
  128.   /* Set up window */
  129.   if(E(saveas_set_file_name(0, newblk->saveas_id, savepath))
  130.   || E(saveas_set_file_type(0, newblk->saveas_id, output_type))
  131.   || E(saveas_set_file_size(0, newblk->saveas_id, flex_size(buffer))))
  132.     goto errexit_menuremove;
  133.  
  134.   if(compress) {
  135.     /* Register extra handler for filetype selection */
  136.     if(E(event_register_toolbox_handler(newblk->window_id, StringSet_ValueChanged, _SaveFile_typehandler, newblk)))
  137.       goto errexit_menuremove;
  138.   }
  139.  
  140.   /* Register other handlers
  141.      Note that ObjectDeleted handler is registered AFTER anything that could cause an error and therefore premature deletion!
  142.   */
  143.   if(E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveToFile, _SaveFile_savehandler, newblk))
  144.   || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_FillBuffer, _SaveFile_ramhandler, newblk))
  145.   || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveCompleted, _SaveFile_savecompleted, newblk))
  146.   || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_DialogueCompleted, delete_object_handler, newblk))
  147.   || E(event_register_toolbox_handler(newblk->window_id, ActionButton_Selected, _SaveFile_buttonshandler, newblk))
  148.   || E(event_register_toolbox_handler(newblk->saveas_id, Toolbox_ObjectDeleted, _SaveFile_deletedhandler, newblk)))
  149.     goto errexit_menuremove;
  150.  
  151.   flex_reanchor(&newblk->buffer, buffer);
  152.   return newblk->saveas_id; /* success */
  153.  
  154.   errexit_menuremove:
  155.     RE(ViewsMenu_remove(newblk->saveas_id));
  156.   errexit_delete:
  157.     RE(toolbox_delete_object(0, newblk->saveas_id));
  158.   errexit_free:
  159.     free(newblk->reset_file_name);
  160.     free(newblk);
  161.     return NULL_ObjectId;
  162. }
  163.  
  164. /* ----------------------------------------------------------------------- */
  165. /*                         Private functions                               */
  166.  
  167. /*
  168.  * Toolbox event handlers
  169.  */
  170.  
  171. static int _SaveFile_typehandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  172. {
  173.   /* New file type selected from StringSet */
  174.   StringSetValueChangedEvent *ssvce = (StringSetValueChangedEvent *)event;
  175.   SaveFileBlk *blk = (SaveFileBlk *)handle;
  176.  
  177.   int hextype;
  178.   sscanf(strchr(ssvce->string, '('), "(&%x)", &hextype);
  179.   RE(saveas_set_file_type(0, blk->saveas_id, hextype))
  180.  
  181.   return 1; /* claim event */
  182. }
  183.  
  184. /* ----------------------------------------------------------------------- */
  185.  
  186. static int _SaveFile_savehandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  187. {
  188.   SaveAsSaveToFileEvent *save_to_file_block = (SaveAsSaveToFileEvent *)event;
  189.   SaveFileBlk *blk = (SaveFileBlk *)handle;
  190.   unsigned int flags = 0;
  191.  
  192.   int file_type;
  193.   if(E(saveas_get_file_type(0, id_block->self_id, &file_type)))
  194.     goto exit;
  195.  
  196.   _kernel_oserror *err;
  197.   if(!blk->compress)
  198.     err = perc_operation(FILEPERC_OP_SAVE, save_to_file_block->filename, file_type, &blk->buffer);
  199.   else
  200.     err = perc_operation(FILEPERC_OP_COMP, save_to_file_block->filename, file_type, &blk->buffer);
  201.   if(err != NULL)
  202.     err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
  203.   else
  204.     flags = 1; /* success */
  205.  
  206. exit:
  207.   saveas_file_save_completed(flags, id_block->self_id, save_to_file_block->filename);
  208.   return 1; /* claim event */
  209. }
  210.  
  211. /* ----------------------------------------------------------------------- */
  212.  
  213. static int _SaveFile_ramhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  214. {
  215.   SaveAsFillBufferEvent *fill_buffer_event = (SaveAsFillBufferEvent *)event;
  216.   SaveFileBlk *blk = (SaveFileBlk *)handle;
  217.   int bytes_to_go, chunk_size, buffer_size;
  218.  
  219.   if(blk->no_budge) {
  220.     blk->no_budge = false;
  221.     nobudge_deregister();
  222.   }
  223.  
  224.   buffer_size = flex_size((flex_ptr)&blk->buffer);
  225.  
  226.   if(fill_buffer_event->no_bytes > buffer_size)
  227.     /* Already sent all data */
  228.     chunk_size = 0;
  229.   else {
  230.     /* Calculate bytes still to send */
  231.     bytes_to_go = buffer_size - fill_buffer_event->no_bytes;
  232.     if(bytes_to_go > fill_buffer_event->size)
  233.       /* Can't fit remaining, so just fill buffer */
  234.       chunk_size = fill_buffer_event->size;
  235.     else
  236.       /* Send all of remaining data */
  237.       chunk_size = bytes_to_go;
  238.   }
  239.  
  240.   nobudge_register(1024);
  241.   blk->no_budge = true;
  242.  
  243.   RE(saveas_buffer_filled(0, id_block->self_id, (void *)((int)blk->buffer + fill_buffer_event->no_bytes), chunk_size))
  244.  
  245.   return 1; /* claim event */
  246. }
  247.  
  248. /* ----------------------------------------------------------------------- */
  249.  
  250. static int _SaveFile_savecompleted(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  251. {
  252.   /* Save completed */
  253.   SaveFileBlk *blk = (SaveFileBlk *)handle;
  254.  
  255.   if(blk->no_budge) {
  256.     blk->no_budge = false;
  257.     nobudge_deregister();
  258.   }
  259.  
  260.   return 1; /* claim event */
  261. }
  262.  
  263. /* ----------------------------------------------------------------------- */
  264.  
  265. static int _SaveFile_buttonshandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  266. {
  267.   ActionButtonSelectedEvent *abse = (ActionButtonSelectedEvent *)event;
  268.   SaveFileBlk *blk = (SaveFileBlk *)handle;
  269.  
  270.   if(!FLAG_SET(abse->hdr.flags, ActionButton_Selected_Adjust))
  271.     return 0; /* not interested */
  272.   
  273.   switch(id_block->self_component) {
  274.     case 0x82bc02: /* Cancel button */
  275.       /* Reset dbox state */    
  276.       if(blk->reset_file_name != NULL)
  277.         RE(saveas_set_file_name(0, blk->saveas_id, blk->reset_file_name));
  278.     
  279.       RE(stringset_set_selected(0, id_block->self_id, SAVEFILE_SSFILETYPE, blk->reset_filetype));
  280.       int hextype;
  281.       sscanf(strchr(blk->reset_filetype, '('), "(&%x)", &hextype);
  282.       RE(saveas_set_file_type(0, blk->saveas_id, hextype));
  283.       break;
  284.       
  285. #ifndef SAVEAS_CRAP /* no point saving state if dbox closes anyway */
  286.     case 0x82bc03: /* Save button */
  287.       /* Record dbox state */
  288.       RE(stringset_get_selected(0, id_block->self_id, SAVEFILE_SSFILETYPE, &blk->reset_filetype, sizeof(blk->reset_filetype), NULL));
  289.  
  290.       int len;
  291.       E_RETV(saveas_get_file_name(0, blk->saveas_id, NULL, 0, &len), 1)
  292.       free(blk->reset_file_name);
  293.       blk->reset_file_name = malloc(len+1);
  294.       if(blk->reset_file_name == NULL)
  295.         err_complain(255, msgs_global("NoMem"));
  296.       else
  297.         RE(saveas_get_file_name(0, blk->saveas_id, blk->reset_file_name, len, NULL))
  298.       break;
  299. #endif
  300.  
  301.     default:
  302.       return 0; /* unknown component */
  303.   }
  304.  
  305.   return 1; /* claim event */
  306. }
  307.  
  308. /* ----------------------------------------------------------------------- */
  309.  
  310. static int _SaveFile_deletedhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  311. {
  312.   SaveFileBlk *blk = (SaveFileBlk *)handle;
  313.  
  314.   if(blk->no_budge) {
  315.     blk->no_budge = false;
  316.     nobudge_deregister();
  317.   }
  318.  
  319.   /* Deregister handlers */
  320.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveToFile, _SaveFile_savehandler, handle));
  321.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_FillBuffer, _SaveFile_ramhandler, handle));
  322.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveCompleted, _SaveFile_savecompleted, handle));
  323.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_DialogueCompleted, delete_object_handler, handle));
  324.   RE(event_deregister_toolbox_handler(blk->window_id, ActionButton_Selected, _SaveFile_buttonshandler, handle));
  325.   RE(event_deregister_toolbox_handler(id_block->self_id, Toolbox_ObjectDeleted, _SaveFile_deletedhandler, handle));
  326.  
  327.   if(blk->compress)
  328.     /* Deregister extra handler for filetype selection */
  329.     RE(event_deregister_toolbox_handler(blk->window_id, StringSet_ValueChanged,  _SaveFile_typehandler, handle));
  330.  
  331.   /* Remove from iconbar menu */
  332.   RE(ViewsMenu_remove(id_block->self_id));
  333.  
  334.   /* free memory */
  335.   flex_free(&blk->buffer);
  336.   free(blk->reset_file_name);
  337.   free(blk);
  338.  
  339.   if(last_savebox == id_block->self_id)
  340.    last_savebox = NULL_ObjectId;
  341.  
  342.   return 1; /* claim event */
  343. }
  344.